#include "./Grid.h"
#include <QGraphicsScene>
Box::Box(Facility *m):master(m){}

/// @brief 格子的析构,当且仅当游戏结束时 发生,
/// 并且不会对前两个指针进行析构
Box::~Box(){
    master = null;
    if(object_qt){
        object_qt->scene()->removeItem(object_qt);
        delete object_qt;
        object_qt = null;
    }
}

Grid::Grid(int height, int width )
    :height(height),width(width),
    grids(width,std::vector<Box>(height))
{}

bool Grid::CanPlace(const Coordinate& co, int w, int h){
    for(int li = 0; li < w; ++li){
        int i = co.x+li;
        for(int lj = 0; lj < h; ++lj){
            int j = co.y+lj;
            if(isValid(i,j) &&
                (grids[i][j].master == null
                 || grids[i][j].master->getFacilityType() == FacilityType::BELT)){
                continue;
            }else {return false;}
        }
    }
    return true;
}

// 放置设备，并返回这个范围要清理的设备
std::unordered_set<Facility *> Grid::setFacility(Facility *facility, const Coordinate& co, int w, int h){
    std::unordered_set<Facility *> res;
    for(int li = 0; li < w; ++li){
        int i = co.x+li;
        for(int lj = 0; lj < h; ++lj){
            int j = co.y+lj;
            if(grids[i][j].master == null){
                grids[i][j].master = facility;
            }
            else if(facility == null){ // 清理
                res.insert(grids[i][j].master);
                grids[i][j].master = null;
            }
            else if(grids[i][j].master->getFacilityType() == FacilityType::BELT){
                res.insert(grids[i][j].master);
                grids[i][j].master = facility;
            }
            else if(facility != null){
                std::cerr << "wtf?\n";
            }
        }
    }
    return res;
}

// 返回这个范围的邻居设备
std::unordered_set<Facility *> Grid::surroundingFacilities(const Coordinate& co, int w, int h){
    std::unordered_set<Facility *> res;
    int x = co.x, y = co.y;
    int cx = 0, cy = 0;

    cy = y - 1;
    if(0 <= cy && cy < height)
    {
        for(int i = -1; i < w; ++i){
            cx = x + i;
            if(0 <= cx && cx < width){
                if(grids[cx][cy].master)
                    res.insert(grids[cx][cy].master);
            }
        }
    }
    cx = x + w;
    if(0 <= cx && cx < width)
    {
        for(int i = -1; i < h; ++i){
            cy = y + i;
            if(0 <= cy && cy < height){
                if(grids[cx][cy].master)
                    res.insert(grids[cx][cy].master);
            }
        }
    }
    cy = y + h;
    if(0 <= cy && cy < height)
    {
        for(int i = 0; i <= w; ++i){
            cx = x + i;
            if(0 <= cx && cx < width){
                if(grids[cx][cy].master)
                    res.insert(grids[cx][cy].master);
            }
        }
    }
    cx = x - 1;
    if(0 <= cx && cx < width)
    {
        for(int i = 0; i <= h; ++i){
            cy = y + i;
            if(0 <= cy && cy < height){
                if(grids[cx][cy].master)
                    res.insert(grids[cx][cy].master);
            }
        }
    }

    return res;
}

Grid::~Grid(){}
